import { DownOutlined, UpOutlined } from "@ant-design/icons";
import { useControllableValue } from "ahooks";
import classNames from "classnames";
import React, { useContext, useEffect, useRef } from "react";
import getPrefixCls from "./utils";
import { PipelineContext } from "./index";
import { stageContext } from "./Stage";
import type { Status } from "./types";
import { isStatusBuiltIn, StatusIcon } from "./util";

export interface TaskProps {
  /**
   * 类名
   */
  className?: string;
  /**
   * 样式
   */
  style?: React.CSSProperties;
  /**
   * 标题样式
   */
  titleStyle?: React.CSSProperties;
  /**
   * 用户传入的title样式
   */
  textStyle?: React.CSSProperties;
  /**
   * className 前缀
   */
  prefixCls?: string;
  /**
   * 必填，任务标识，要求在同一个 Stage 内唯一，在不同 Stage 间可以不唯一
   */
  name: string;
  /**
   * 任务名称
   */
  title?: React.ReactNode;
  /**
   * 任务描述
   */
  description?: React.ReactNode;
  /**
   * 任务状态
   */
  status?: Status;
  /**
   * process 状态的进度值
   */
  percent?: number;
  /**
   * 任务操作区
   */
  extra?: React.ReactNode;
  /**
   * 连线目标，指定下一个阶段内某些任务的 name 值，不能往前或者跨越阶段连线。当需要汇总连线时，可以设置 join 为 true。
   */
  lineTo?: (string | { join: boolean; taskName: string })[];
  /**
   * 是否默认展开
   */
  defaultExpanded?: boolean;
  /**
   * 是否展开
   */
  expanded?: boolean;
  /**
   * 任务展开回调
   */
  onExpand?: (taskName: string, expanded: boolean) => void;
  /**
   * @description 手动添加children申明
   */
  children?: any;

  stageName?: string;

  offsetY?: number;
  onClick?: () => void;
}

const Task: React.FC<
  TaskProps & {
    index?: number;
  }
> = (props) => {
  const {
    className,
    style,
    prefixCls: customizePrefixCls,
    children,
    name,
    title,
    description,
    status,
    percent,
    extra,
    titleStyle,
    textStyle,
    // expanded,
    defaultExpanded,
    onExpand,
    onClick = () => {},
    offsetY,
    index,
  } = props;

  let taskIndexInStage = index;
  const { stageName, stageIndex } = useContext(stageContext);

  const { lineMap } = useContext(PipelineContext);

  let isCrossList = 0;

  lineMap.forEach((line) => {
    const taskIndex = stageIndex * 100 + taskIndexInStage;

    line.forEach((subLine) => {
      //  [[10,20],[20,70]] ，30 就会挡住 20-70 这条线，但是 31 不会
      if (
        taskIndex > subLine.formIndex &&
        taskIndex < subLine.toIndex &&
        (subLine.formIndex % 100 === taskIndexInStage ||
          (subLine.toIndex % 100 === taskIndexInStage &&
            // 如果两个人任何横跨三个节点就不会挡住
            Math.abs(subLine.toIndex - subLine.formIndex) > 200))
      ) {
        isCrossList += 1;
        taskIndexInStage = taskIndexInStage + 1;
      }
    });
  });
  /**
   * 往下移动之后要重新计算线的位置
   */
  if (taskIndexInStage !== index) {
    const taskIndex = stageIndex * 100 + index;
    const list = lineMap.get(name).map((item) => {
      if (item.formIndex === taskIndex) {
        return {
          ...item,
          originFormIndex: item.formIndex,
          formIndex: stageIndex * 10 + taskIndexInStage,
        };
      }

      if (item.toIndex === taskIndex) {
        return {
          ...item,
          originToIndex: item.toIndex,
          toIndex: stageIndex * 10 + taskIndexInStage,
        };
      }
      return item;
    });
    lineMap.set(name, list);
  }

  const [isExpanded, setIsExpanded] = useControllableValue(props, {
    defaultValue: defaultExpanded,
    valuePropName: "expanded",
  });

  const prefixCls = getPrefixCls("pipeline", customizePrefixCls);
  const taskCls = `${classNames(prefixCls)}-task`;

  const enableExpander = children !== undefined;
  const statusBuiltIn = isStatusBuiltIn(status);

  const handleExpand = () => {
    if (!enableExpander) {
      return;
    }
    setIsExpanded(!isExpanded);
    onExpand?.(name, !isExpanded);
  };
  const taskDomRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!taskDomRef.current) return;
  }, [isExpanded]);

  return (
    <div
      style={{
        ...style,
        marginTop: isCrossList ? isCrossList * (offsetY || 48) : undefined,
      }}
      className={classNames(taskCls, className)}
      onClick={() => onClick()}
    >
      <div
        className={classNames(
          {
            [`${taskCls}-card`]: true,
            [`${taskCls}-card-expanded`]: isExpanded,
          },
          statusBuiltIn && {
            [`${taskCls}-card-status-${status}`]: true,
            [`${taskCls}-card-status-${status}-hover`]: enableExpander,
          }
        )}
        onClick={handleExpand}
        data-task-name={name}
        data-stage-name={stageName}
      >
        <div className={`${taskCls}-card-title`} style={titleStyle}>
          <div className={`${taskCls}-card-title-left`}>
            {status && (
              <StatusIcon
                prefixCls={prefixCls}
                className={`${taskCls}-card-title-left-status`}
                status={status}
                percent={percent}
              />
            )}
            {title && (
              <span
                className={`${taskCls}-card-title-left-text`}
                style={textStyle}
              >
                {title}
              </span>
            )}
          </div>
          {extra || enableExpander ? (
            <div className={`${taskCls}-card-title-right`}>
              {extra && (
                <React.Fragment>
                  <div className={`${taskCls}-card-title-right-extra`}>
                    {extra}
                  </div>
                  <div className={`${taskCls}-card-title-right-divider`} />
                </React.Fragment>
              )}
              {enableExpander && (
                <div className={`${taskCls}-card-title-right-expander`}>
                  {isExpanded ? <UpOutlined /> : <DownOutlined />}
                </div>
              )}
            </div>
          ) : null}
        </div>
        {description && (
          <div className={`${taskCls}-card-title-description`}>
            {description}
          </div>
        )}
      </div>
      {isExpanded && <div className={`${taskCls}-detail`}>{children}</div>}
    </div>
  );
};

export default Task;
